import java.util.ArrayList;
import java.util.List;

/**
 * 组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
 * 有透明模式，和安全模式，主要区别是安全模式下，叶子节点和树枝节点具有相同的接口，客户端可以一致的使用它们。
 * 比如：一个大文件夹里面包含了 无数个小文件夹和文件，使用组合模式，可以很方便的遍历整个文件夹，获取文件的个数。
 */
public class CompositePattern {
    public static void main(String[] args) {
        // 创建文件夹
        Folder root = new Folder("root",new ArrayList<>());
        // 创建文件夹
        Folder folder1 = new Folder("folder1",new ArrayList<>());
        //root 添加文件夹
        root.addFile(folder1);
        // 创建文件夹
        Folder folder2 = new Folder("folder2",new ArrayList<>());
        //folder1 添加文件夹
        folder1.addFile(folder2);
        // 创建文件
        File file1 = new File("file1",100);
        // 创建文件
        File file2 = new File("file2",200);
        // 文件夹1 添加文件
        folder1.addFile(file1);
        // 文件夹2 添加文件
        folder2.addFile(file2);
        //获取文件个数
        System.out.println(root.fileSum());
    }
}
// 抽象构件
interface Component {
    Integer fileSum();
}
// 叶子构件(文件夹)
class File  implements Component{
    String name;
    Integer size;
    public File(String name,Integer size){
        this.name = name;
        this.size = size;
    }

    @Override
    public Integer fileSum() {
        return size;
    }
}
// 树枝构件(文件夹操作)
class Folder implements Component{
    //有文件夹，有文件，可以进行操作
    String folderName;
    List<Component> children = new ArrayList<>();
    public Folder(String folderName,List<Component> children){
            this.folderName = folderName;
            this.children = children;
    }
    //新增文件夹或者文件
    public void addFile(Component component){
        children.add(component);
    }
    //删除文件夹或者文件
    public void removeFile(Component component){
        children.remove(component);
    }

    @Override
    public Integer fileSum() {
        Integer sum = 0;
        for (Component component : children) {
            sum+=component.fileSum();
        }
        return sum;
    }
}
